package asteroids.model;

import be.kuleuven.cs.som.annotate.*;

/**
 * A class representing bullets.
 * @invar Every bullet has a proper ship.
 * 			| getShip() != null
 * @invar A bullet can't bounce more than once of a wall.
 * 			| getBounced() <= 1
 * @author Martin & Anton
 *
 */
public class Bullet extends SpaceObject {
	
	private static final double density = 7.8E12;
	private final Ship ship;
	private int bounced;
	
	/**
	 * 
	 * @param x
	 * @param y
	 * @param speed_x
	 * @param speed_y
	 * @param radius
	 * @param ship
	 * @throws IllegalArgumentException
	 */
	public Bullet(double x, double y, double speed_x, double speed_y,double radius, Ship ship)	throws IllegalArgumentException {
		this(x, y, speed_x, speed_y, radius, c, ship);
	}
	
	/**
	 * 
	 * @param x
	 * @param y
	 * @param speed_x
	 * @param speed_y
	 * @param radius
	 * @param max_speed
	 * @param ship
	 * @throws IllegalArgumentException
	 */
	public Bullet(double x, double y, double speed_x, double speed_y,double radius, double max_speed, Ship ship)	throws IllegalArgumentException {
		super(x, y, speed_x, speed_y, radius, (4/3)*Math.PI*Math.pow(radius, 3)*density, 0, c);
		if(ship == null)
			throw new IllegalArgumentException();
		this.ship = ship;
		this.bounced = 0;
	}
	
	@Basic @Immutable
	public Ship getShip(){
		return this.ship;
	}
	
	@Basic
	private int getBounced() {
		return bounced;
	}
	
	/**
	 * This method will increase the bounced parameter by one, if it is 0, else it will do nothing.
	 * @post	If bounced is 0, it will increased bounced by one.
	 * 			|if(getBounced() == 0)
	 * 			|	Then (new this).getBounced() == this.getBounced() + 1
	 */
	private void incrBounced() {
		if(getBounced() == 0)
			bounced++;
	}
	
	/**
	 * 
	 * The method to bounce of a wall, but also increases a integer 'bounced' so we can keep track of how much it bounces.
	 * @effect  if(bounce < 1) Then super.bounceWall()
	 * @post	The counter will go up, if th bullet has not bounced yet.
	 * 			| if(bounced == 0) bounced
	 */
	@Override
	public void bounceWall() {
		if(getBounced() == 0) {
			super.bounceWall();
			incrBounced();
		}
		else if(getBounced() >= 1){
			this.getWorld().removeSpaceObject(this);
		}
	}
	
	/**
	 * This method removes all references to the object and sets its status to dead.
	 * The method works the same as the method in SpaceObject, except it also rmoves thr bullet 
	 * from the bullet list from its ship.
	 * @effect	getShip.removeBullet(this)
	 * 			| isAlive())
	 * @effect	super.die()
	 * 			| isAlive())
	 */
	@Override
	public void die() {
		if(isAlive()) {
			getShip().removeBullet(this);
			super.die();
		}
	}
}
